package com.amkai.aes.webservice.binary.objecthandler.prefcards;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Query;

import com.amkai.aes.aescommon.service.binary.job.prefcards.PrefCardLazyResolver;
import com.amkai.aes.aescommon.service.binary.job.prefcards.PrefCardQueryParams;
import com.amkai.aes.aescommon.service.binary.job.prefcards.PrefCardQueryResult;
import com.amkai.aes.aescommon.service.binary.job.prefcards.PreferenceCardQueryJob;
import com.amkai.aes.generatedbeans.organization.Department;
import com.amkai.aes.generatedbeans.preferencecard.PreferenceCard;
import com.amkai.aes.webservice.binary.JobObjectHandler;
import com.amkai.common.extensions.hibernate.config.SiteManager;
import com.amkai.common.extensions.hibernate.config.manager.SessionManager;

public class PreferenceCardQueryHandler implements JobObjectHandler<PreferenceCardQueryJob, PrefCardQueryParams, PrefCardQueryResult> {
	private static final Log logger = LogFactory.getLog(PreferenceCardQueryHandler.class);
	
	private static final String OBJECT_PREFIX="pref";
	
	private static final String ALL_QUERY = "select pref FROM PreferenceCard pref "
		+ " LEFT JOIN FETCH pref.provider as prov "
		+ " LEFT JOIN FETCH pref.mainCode "
		+ " LEFT JOIN FETCH pref.anestType "
		//#14873 add busines entity as param for filtering
		+ " where pref.deleted = 0 AND pref.businessEntity = :be";
	
	@Override
	public PrefCardQueryResult process(PreferenceCardQueryJob job,
			PrefCardQueryParams params) throws Exception {
		PrefCardQueryResult result = new PrefCardQueryResult();
		SessionManager sm = null;
		try {
			sm = SiteManager.Start();
			sm.openSession();
			
			result.setPrefCards(getResultData(params, job.getModuleDepartment(), sm));
		} catch (Exception e) {
			logger.error("PreferenceCardQueryHandler: ", e);
			throw e;
		} finally {
			if (sm != null) {
				sm.closeSession();
			}
		}
		return result;
	}
	private List<PreferenceCard> getResultData(PrefCardQueryParams params,
			Department moduleDepartment, SessionManager sm) {
		
		StringBuilder query = new StringBuilder(ALL_QUERY);
		List<NameIdListPair> queryParams = new ArrayList<NameIdListPair>();
		addWhereCondition(params, query, queryParams, "specialty", params.getSpecialties());
		addWhereCondition(params, query, queryParams, "provider", params.getSurgeons());
		addWhereCondition(params, query, queryParams, "anestType", params.getAnestTypes());
		addWhereCondition(params, query, queryParams, "mainCode", params.getProcedures());
		
		logger.debug(query.toString());
		
		//#14873 add BE as param
		Query hibQuery = sm.execute(query.toString()).setEntity("be", params.getBusinesEntity());
		for (NameIdListPair pair : queryParams) {
			hibQuery.setParameterList(pair.getName(), pair.getIdList());
		}
		List<?> items = hibQuery.list();
		List<PreferenceCard> result = new ArrayList<PreferenceCard>();
		for (Object item : items) {
			PreferenceCard card = (PreferenceCard)item;
			PrefCardLazyResolver.resolve(card);

			result.add(card);
		}
		
		return result;
	}

	private void addWhereCondition(PrefCardQueryParams params,
			StringBuilder query, List<NameIdListPair> queryParams,
			String variableName, List<Long> idList) {
		if (!idList.isEmpty()) {
			String hqlVariableName = variableName + "List";
			query.append(" and ").append(OBJECT_PREFIX).append(
					".").append(variableName).append(".id in (:").append(hqlVariableName).append(")");
			queryParams.add(new NameIdListPair(hqlVariableName, idList));
		}
	}

	private class NameIdListPair {
		private String name;
		private List<Long> idList;

		public NameIdListPair(String name, List<Long> idList) {
			this.name = name;
			this.idList = idList;
		}

		public String getName() {
			return name;
		}

		public List<Long> getIdList() {
			return idList;
		}
	}

}
